#define _TW88SPI_C_  

#include "config.h"

u8 DMAMODE_RW_FIX_REG = 0x64;
u8 DMAMODE_RW_INC_REG = 0x44;
u8 DMAMODE_R_XDATA    = 0xc4;
u8 DMAMODE_W_XDATA    = 0xc4;
u8 SPICMD_READ        = 0x03;
u8 SPICMD_PROGRAM     = 0x02;
u8 SPICMD_u8S		= 5;

//=============================================================================
//
//=============================================================================
u8 SPI_SetModeByRegister( void )
{
	u8 mod;

	WriteTW88Page( PAGE4_SPI );
	mod = ReadTW88( 0xc0 ) & 0x07;
    //Printf("\nTW8835 REG 0x4C0[2:0](SPI FLASH read mode) is: %02bx", mod );
    
	switch( mod ) {
		case 0:	//--- Slow
			DMAMODE_RW_FIX_REG = 0x64;
			DMAMODE_RW_INC_REG = 0x44;
			DMAMODE_R_XDATA    = 0xc4;
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0x03;	SPICMD_u8S = 4;
			SPICMD_PROGRAM     = 0x02;
			break;

		case 1:	//--- Fast
			DMAMODE_RW_FIX_REG = 0x65;
			DMAMODE_RW_INC_REG = 0x45;
			DMAMODE_R_XDATA    = 0xc5;
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0x0b;	SPICMD_u8S = 5;
			SPICMD_PROGRAM     = 0x02;
			break;

		case 2:	//--- Dual
			DMAMODE_RW_FIX_REG = 0x65;
			DMAMODE_RW_INC_REG = 0x45;
			DMAMODE_R_XDATA    = 0xc5;
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0x3b;	SPICMD_u8S = 5;
			SPICMD_PROGRAM     = 0x02;
			break;

		case 3:	//--- Quad
			DMAMODE_RW_FIX_REG = 0x65;
			DMAMODE_RW_INC_REG = 0x45;
			DMAMODE_R_XDATA    = 0xc5;
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0x6b;	SPICMD_u8S = 5;
			SPICMD_PROGRAM     = 0x02;
			break;

		case 4:	//--- Dual-IO
			DMAMODE_RW_FIX_REG = 0x65;
			DMAMODE_RW_INC_REG = 0x45;
			DMAMODE_R_XDATA    = 0xc5;
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0xbb;	SPICMD_u8S = 5;
			SPICMD_PROGRAM     = 0x02;
			break;

		case 5:	//--- Quad-IO
			DMAMODE_RW_FIX_REG = 0x67;
			DMAMODE_RW_INC_REG = 0x47;
			DMAMODE_R_XDATA    = 0xc7;	
			DMAMODE_W_XDATA    = 0xc4;
			SPICMD_READ        = 0xeb;	 SPICMD_u8S = 7;
			SPICMD_PROGRAM     = 0x02;
			break;
 	}
	return mod;
}

//return
//	0: fail or MX. default
//	1: EON
//	
u8 SPI_QUADInit(void)
{
	u8	temp;
	u8 ret=0;

	WriteTW88Page( PAGE4_SPI );

	WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
	WriteTW88( 0xca, 0x9f );					// cmd, read Jedec ID
	WriteTW88( 0xc6, 0x04 );
	WriteTW88( 0xc7, 0xd0 );						// read buffer size 3

	WriteTW88( 0xda, 0 );
	WriteTW88( 0xc8, 0 );
	WriteTW88( 0xc9, 3 );						// read buffer size 3
	WriteTW88( 0xc4, 0x01 );					// start

	temp = ReadTW88(0xd0);
	//Printf("\nSPI JEDEC ID: %02bx %02bx %02bx", temp, ReadTW88(0xd1), ReadTW88(0xd2) );


	if ( (temp == 0xC2) || ( temp == 0x1c)) {		// for MX	&& EON  && STM
		if(temp ==0x1C)
			ret = SFLASH_VENDOR_EON;
		else
			ret = SFLASH_VENDOR_MX;

		WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0x05 );					// cmd, read Status
		WriteTW88( 0xc9, 1 );						// read buffer size 1
		WriteTW88( 0xc4, 0x01 );					// start
		temp = ReadTW88( 0xd0 );					// read status regisiter value
		//Printf("\nSPI FLASH Status is: %02bx", temp );
		if ((temp == 0x00)||(temp == 0x3c)){
//			if(ret== SFLASH_VENDOR_EON)
//				Puts("\nEnable EON quad mode" );
//			else 
//				Puts("\nEnable MX quad mode" );
			WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x06 );					// cmd, write enable
			WriteTW88( 0xc9, 0 );						// read buffer size 1
			WriteTW88( 0xc4, 0x03 );					// start

//			Puts("\nWrite ENABLED" );

			WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x05 );					// cmd, read Status
			WriteTW88( 0xc9, 1 );						// read buffer size 1
			WriteTW88( 0xc4, 0x01 );					// start
			temp = ReadTW88( 0x10 );					// read status regisiter value
			//Printf("\nStatus after Write enable %02bx", temp );

			WriteTW88( 0xc3, 0x42 );					// mode, cmd-len 2
			WriteTW88( 0xca, 0x01 );					// cmd, write Status
			WriteTW88( 0xcb, 0x40 );					// cmd, en QAUD mode
			WriteTW88( 0xc9, 0 );						// read buffer size 1
			WriteTW88( 0xc4, 0x07 );					// start + write + busycheck

//			Puts("\nQUAD ENABLED" );

			WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x05 );					// cmd, read Status
			WriteTW88( 0xc9, 1 );						// read buffer size 1
			WriteTW88( 0xc4, 0x01 );					// start
			temp = ReadTW88( 0xd0 );					// read status regisiter value
			//Printf("\nStatus after QUAD enable %02bx", temp );

			WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x06 );					// cmd, write disable
			WriteTW88( 0xc4, 0x01 );					// start
		}
	}
	else if ( temp == 0xEF ) {				// for WB
		ret = SFLASH_VENDOR_WB;
		WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0x05 );					// cmd, read Status
		WriteTW88( 0xc9, 2 );						// read buffer size 1
		WriteTW88( 0xc4, 0x01 );					// start
		temp = ReadTW88( 0xd1 );					// read status regisiter value
		if ( temp == 0 ) {
//			Puts("\nEnable WB quad mode" );
			WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x06 );					// cmd, write enable
			WriteTW88( 0xc4, 0x01 );					// start

			WriteTW88( 0xc3, 0x43 );					// mode, cmd-len 1
			WriteTW88( 0xca, 0x01 );					// cmd, write Status
			WriteTW88( 0xcb, 0x00 );					// cmd, en QAUD mode
			WriteTW88( 0xcc, 0x02 );					// cmd, en QAUD mode
			WriteTW88( 0xc4, 0x01 );					// start
		}
	}
	else if(temp == 0x20 ) {				// for STM
		ret = SFLASH_VENDOR_NUM;
		//Puts("\nEnable Numonyx quad mode" );

		WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0x06 );					// cmd, write enable
		WriteTW88( 0xc9, 0 );						// read buffer size 1
		WriteTW88( 0xc4, 0x03 );					// start

		WriteTW88( 0xc3, 0x43 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0xB1 );					// cmd, write enable
		WriteTW88( 0xcb, 0x6F );
		WriteTW88( 0xcc, 0xFF );
		WriteTW88( 0xc9, 0 );						// read buffer size 1
		WriteTW88( 0xc4, 0x07 );					// start

		WriteTW88( 0xc3, 0x41 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0x06 );					// cmd, write enable
		WriteTW88( 0xc9, 0 );						// read buffer size 1
		WriteTW88( 0xc4, 0x03 );					// start

		WriteTW88( 0xc3, 0x42 );					// mode, cmd-len 1
		WriteTW88( 0xca, 0x81 );					// cmd, write enable
		WriteTW88( 0xcb, 0x6B );
		WriteTW88( 0xc9, 0 );						// read buffer size 1
		WriteTW88( 0xc4, 0x07 );					// start

		//Puts("--DONE");
	}
	return ret;
}

//=============================================================================
//
//=============================================================================
void TW8825_SPI_Init(void)
{
	WriteTW88( 0xff, PAGE4_SPI );
	
	WriteTW88( TWBASE_SPI, SPI_READ_MODE );		// SPI Mode:	0=Slow, 1=fast, 2=dual, 3=quad, 4=dual-io, 5=quad-io
												// R4C0	SPI mode QuadIO
//	WriteTW88( 0xc1, 0x06 );					// MCU Clock:	27MHz
//	WriteTW88( 0xc2, 0x06 );					// SPI Clock:	27MHz

//	dat = ReadTW88( 0x20 ) | 0x2c;				//----- Enable OSD-DMA, Cache
//	WriteTW88( 0x20, dat );
	SPI_QUADInit();
	SPI_SetModeByRegister();					// Match DMA mode with SPI-read
	
	WriteTW88Page( PAGE0_GENERAL );
	WriteTW88( 0x02, 0xFF );	// Clear Pending Interrupts
	WriteTW88( 0x03, 0xFE );	// enable SW. disable all other interrupts	

}

